import requests
import json
import urllib3
import tushare as ts
import pandas as pd
import time
import numpy as np

# for InsecureRequestWarning
urllib3.disable_warnings()

# 卖出手续费
cost_sold = 0.0013
cost_buy = 0.0003

# 股票信息
tushare_flag = False
# tushare_flag = True

# 写入新数据（注意：会有访问强度限制）
if tushare_flag:
    df = ts.get_today_all()
    df.sort_values(by=['trade', 'open'], ascending=False).to_csv(
        r'./BigWork/src/today.csv')
#
else:
    df = pd.read_csv(r'./BigWork/src/today.csv', encoding='utf-8')
print('csv............................')


def get_response_json(url):
    headers1 = {
        'Host': 'bigquant.com',
        'Connection': 'keep-alive',
        'Accept': 'application/json, text/plain, */*',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36',
    }
    response = requests.get(url=url, headers=headers1, verify=False)

    # 解析json
    response_json = json.loads(response.text)
    return response_json


# 策略的排名
def get_share_algo_lists(owner='yilong_10'):
    share_algo_lists = []

    # 查寻作者id
    url_share_algo_lists = 'https://bigquant.com/bigwebapi/algo_list/share?page=1&limit=10&order_by=-grade&search='+owner
    # url_share_algo_lists = 'https://bigquant.com/bigwebapi/algo_list/share?page=1&limit=10&order_by=-grade&search=yilong_10'
    # print(url_share_algo_lists)

    response_json = get_response_json(url_share_algo_lists)

    share_algo_lists = response_json['data']['share_algo_lists']

    return share_algo_lists


# 股票策略搜索


def get_strategy(fake_unique_id):
    owner = fake_unique_id[0:9]
    unique_id = fake_unique_id[10:]

    # 其中周六日不算，如果工作日内某天没有交易，那就是空[]。
    # 持仓
    positions_lists = []
    # 交易
    transactions_lists = []
    # 卖出
    slod_transactions_lists = []

    # 持仓详情
    url_positions_lists = 'https://bigquant.com/bigwebapi/algo_info/position?owner=' + \
        owner+'&notebook_id=' + unique_id + '&limit=-1'
    # url_positions_lists = 'https://bigquant.com/bigwebapi/algo_info/position?owner=yilong_10&notebook_id=1a9be36e-6de4-11ea-bc2b-0a580a830103&limit=-1'

    # 交易详情
    url_transactions_lists = 'https://bigquant.com/bigwebapi/algo_info/transaction?owner=' + \
        owner+'&notebook_id=' + unique_id + '&limit=-1'
    # url_transactions_lists = 'https://bigquant.com/bigwebapi/algo_info/transaction?owner=yilong_10&notebook_id=1a9be36e-6de4-11ea-bc2b-0a580a830103&limit=-1'

    # 卖出详情
    url_slod_transactions_lists = 'https://bigquant.com/bigwebapi/algo_info/sold_transaction?owner=' + \
        owner+'&notebook_id=' + unique_id + '&limit=-1'
    # url_slod_transactions_lists = 'https://bigquant.com/bigwebapi/algo_info/sold_transaction?owner=yilong_10&notebook_id=1a9be36e-6de4-11ea-bc2b-0a580a830103&limit=-1'

    # 获取json对象
    positions_lists_response_json = get_response_json(url_positions_lists)
    transactions_lists_response_json = get_response_json(
        url_transactions_lists)
    slod_transactions_lists_response_json = get_response_json(
        url_slod_transactions_lists)

    # 获取列表
    positions_lists = positions_lists_response_json['data']['positions_lists']
    transactions_lists = transactions_lists_response_json['data']['transactions_lists']
    slod_transactions_lists = slod_transactions_lists_response_json[
        'data']['slod_transactions_lists']

    return positions_lists, transactions_lists, slod_transactions_lists


# 今收和昨收
def get_code_yesterday_closing_price_and_today_cloing_price(code_sid):
    yesterday_closing_price = -1.0
    today_cloing_price = -1.0
    url_code_sid = 'https://bigquant.com/bigwebapi/stock/fetch_stock_kline?instrument=' + code_sid
    # url_1 = 'https://bigquant.com/bigwebapi/stock/fetch_stock_kline?instrument=601969.SHA'

    response_code_sid = get_response_json(url_code_sid)

    day_lists = response_code_sid['data']['stock_info']['ohlc']['day']

    return yesterday_closing_price,today_cloing_price

# 计算卖出的今日收益


def get_today_return_sold(positions_lists, slod_transactions_lists, today=None):
    # 卖出的今日收益 = 成交额/成交量/昨日收盘*（1-手续费卖）*仓位
    today_return_sold = -1

    # 成交额
    value = 0
    # 成交量.分为卖则负，买则正。
    amount = 0
    # 昨日收盘
    yesterday_closing_price = 0
    # 仓位
    hold_percent_ratio = 0

    if today == None:
        today = time.strftime("%Y-%m-%d", time.localtime())

    # 在卖出详情中找到某天的情况
    index = 0
    # 股票代码
    code = None    # 防止没找超出下标和为空的两种情况，且用于提供股票代码
    length = len(slod_transactions_lists)
    while index < length:
        if len(slod_transactions_lists[index]) > 0:
            if slod_transactions_lists[index][0]['date'] == today:
                code = slod_transactions_lists[index][0]['sid']
                break
        index += 1

    # 某天卖了
    if code != None:
        # 仓位占比
        hold_percent_ratio = positions_lists[index][0]['hold_percent_ratio']
        today_return_sold = value/amount/yesterday_closing_price * \
            (1-cost_sold)*hold_percent_ratio
    # 没卖自然是0
    else:
        today_return_sold = 0

    return today_return_sold


# 计算今收（现价）


def get_buy_price(today_return, positions_lists, slod_transactions_lists, today=None):
    # 今收 = 当日市值/成交额
    today_closing_price = -1.0
    # 今开 = 今收*（1-0.0003）/[今日收益/仓位 + 1]
    today_openning_price = -1.0
    # 今日收益（买）
    today_return_buy = today_return - \
        get_today_return_sold(positions_lists, slod_transactions_lists)

    if today == None:
        today = time.strftime("%Y-%m-%d", time.localtime())

    # 在持仓详情中找到某天的情况
    index = 0
    flag = False    # 防止没找超出下标和为空的两种情况
    length = len(positions_lists)
    while index < length:
        if len(positions_lists[index]) > 0:
            if positions_lists[index][0]['date'] == today:
                flag = True
                break
        index += 1

    if flag != False:
        # 当日市值
        value = positions_lists[index][0]['value']
        # 成交量
        amount = positions_lists[index][0]['amount']
        # 仓位占比
        hold_percent_ratio = positions_lists[index][0]['hold_percent_ratio']

        today_closing_price = value/amount
        print('\n[today_closing_price]: %3f / %3f = %3f' %
              (value, amount, today_closing_price))

        today_openning_price = today_closing_price * \
            (1-cost_buy)/(today_return_buy/hold_percent_ratio+1)
        print('\n[today_openning_price]:  %3f * (1-%3f) / (%3f/%3f+1) = %3f\n' %
              (today_closing_price, cost_buy, today_return_buy, hold_percent_ratio, today_openning_price))

    return today_closing_price, today_openning_price

# 得到股票的列表


def get_code_lists(today_closing_price, today_openning_price):
    code_lists = []

    diff = 0.01
    # 因为tushare的数据有时候很粗糙（比如1.2写成1，从而有0.1的误差），所以设定逐次增加。
    while len(code_lists) == 0 and diff < 1.0:
        # trade对应today_closing_price今收，对应today_openning_price今开
        a = df[((df['trade'] - today_closing_price) > -diff) &
               ((df['trade'] - today_closing_price) < diff) &
               ((df['open'] - today_openning_price) > -diff) &
               ((df['open'] - today_openning_price) < diff)]

        b = np.array(a['code'])

        code_lists = list(b)
        diff += 0.01
    return code_lists


# ----------------------------test function----------------------------
# 打印综合排序的名字顺序


def print_share_algo_lists_algo_name(share_algo_lists):
    print('----------------------------')
    for i in share_algo_lists:
        print(i['algo_name'])
    print('----------------------------')

# 打印持仓情况


def print_positions_lists(positions_lists):
    print('----------------------------')
    for i in positions_lists:
        if len(i) > 0:
            print(i[0]['date'], i[0]['value'], i[0]['hold_percent_ratio'])
    print('----------------------------')


if __name__ == '__main__':

    owner_lists = ['yilong_10', 'yilong_20', 'yilong_30',
                   'yilong_40', 'yilong_50', 'yilong_60']

    # owner_lists = ['yilong_10', 'yilong_20']

    # 用于看看每个策略是否对应唯一一个，如果是，则写入到result.csv中。不是的话，就需要自己判断一下。
    all_code_lists = []
    just_one_flag = True

    for owner in owner_lists:
        print('----------------------------%s----------------------------' % (owner,))
        share_algo_lists = get_share_algo_lists(owner)

        # 表示选择符合规定的前3个
        count = 0
        for share_algo in share_algo_lists:
            positions_lists, transactions_lists, slod_transactions_lists = get_strategy(
                share_algo['unique_id'])

            # 今日收盘
            today_closing_price, today_openning_price = get_buy_price(
                share_algo['today_return'], positions_lists, slod_transactions_lists)

            # 今天买了(today_closing_price==-1就表示今天没买)
            if today_closing_price != -1:
                print('[策略名字]: %s\n' % (share_algo['algo_name'],))
                code_lists = get_code_lists(
                    today_closing_price, today_openning_price)
                # SHA_SZA_code_lists = get_SHA_SZA_code_lists(code_lists)
                print(code_lists, '\n\n')
                count += 1
                if just_one_flag == True and len(code_lists) == 1:
                    all_code_lists.append(code_lists[0])
                else:
                    just_one_flag = False

            if count == 3:
                break

    if just_one_flag == True:
        print('一一对应，可以去result.csv中复制了............', all_code_lists)
        result_df = pd.DataFrame(np.array(all_code_lists).reshape(1, -1))
        result_df.to_csv(r'./BigWork/src/result.csv')
